class TaskController < ApplicationController
  before_filter :login_required
  
  def find_user_tasks
    # find user's projects' tasks
    @projectid = (session['selectedproject'] || 0).to_i
    @userid = (session['selectedresp'] || 0).to_i
    user_projects = session['user'].project_ids.join(',')
    cond = "done='0' and project_id in (#{user_projects})"
    cond += " and project_id='#{@projectid}'" if @projectid != 0
    cond += " and user_id='#{@userid}'" if @userid != 0
    @tasks = Task.find(:all, :conditions=>cond, :order=>"`order`")
    # add user's tasks without a project_id (happens when we create a new task)
    Task.find(:all, :conditions => "(project_id='0' and user_id='#{session['user']['id']}')").each {|t| @tasks << t }
  end   
  
  def select_task
    find_user_tasks
  end
  
  # Partial
  def display_tasks_done
    @projectid = (session['selectedproject'] || 0).to_i
    @userid = (session['selectedresp'] || 0).to_i    
    user_projects = session['user'].project_ids.join(',')
    cond = "done='1' and project_id in (#{user_projects})"
    cond += " and project_id='#{@projectid}'" if @projectid != 0
    cond += " and user_id='#{@userid}'" if @userid != 0
    @tasksdone = Task.find(:all, :conditions=>cond, :order=>"`order`")
    render(:partial => 'tasksdone')
  end
  
  def index
    select_task
    flash[:notice] = "You can drag tasks to reorder them"
    get_project_resp @projectid
    @resp = find_responsibles
  end
  
  def find_responsibles(project_id=0)
    if(project_id!=0)
      @resp = Project.find(project_id).users
    else  
      @resp = []
      session['user'].projects(true).each { |p|
        p.users.each { |u| @resp << u}
      }
      @resp.uniq!
      @resp = @resp.sort_by {|u| u.name}
    end
  end
  
  def post
    begin
      Task.update(params[:task].keys, params[:task].values)
      rescue
    end
    if(params[:new] and params[:new][:title] != '')
      params[:new][:order] = '0' if params[:new][:order] == ''
      t = Task.new(params[:new])
      t.save
    end
    
    flash[:notice] = "Saved"
    redirect_to(:action => "index")
  end
  
  def priorize
    t = Task.find(params[:id])
    raise "no task for this id" if t == nil
    hm = params[:howmuch].to_i
    if hm < 0 # up
      if t.order > 1
        t.order += hm
        t.save
      else
        tasks = Task.find_all("order >= #{t.order} and id != '#{t.id}' and done!='1'")
        tasks.each {|t|
          t.order -= hm
          t.save
        }
      end
    else hm > 0 # down
      t.order += hm
      t.save
    end
    flash[:notice] = 'task priorized'
    redirect_to(:action => 'index')
  end
  
  def esc_js(js)
   (js || '').gsub(/\r\n|\n|\r/, "\\n").gsub(/["']/) { |m| "\\#{m}" }.gsub(/[~]/) { "'" }
  end
  
  # Ajaxed
  def createnew
    t = Task.new
    t.user_id = session['user']['id']
    t.project_id = session['selectedproject']
    t.order = 0
    t.save
    inner = esc_js(render_to_string(:partial => "task", :locals => {:task => t}))
    render_text "displaynew(#{t.id},'#{inner}')"
    #order
  end
  
  # Ajaxed
  def save
    t_id = params[:id]
    t = Task.find(t_id)
    render_text "$('s#{t_id}').src = image_path('save.png');alert('Can not find task #{t_id}');" and return if t == nil
    
    #user
    uname = params['user']['name']
    u = User.find_by_name(uname)
    render(:text=>"$('s#{t.id}').src='/images/save.png';alert('user #{uname} not found')") and return if u == nil
    
    #project
    pname = params['project']['name']
    projects_by_name = Project.find_all_by_name(pname)
    #p = Project.find_by_sql(["select p.* FROM projects p limit 1"])# p LEFT OUTER JOIN projects_users u ON u.project_id=p.id WHERE p.name= ?",pname])
    if projects_by_name == []
      if(params['C']=='1')
        p = Project.new(:name => pname)
        p.save
        p.users << session['user']
        projects_by_name = [] << p
      else
        render(:text=>"create_project_confirm('#{t_id}');")
        return
      end
    end
    found = nil
    projects_by_name.each do |p|
      found = true and break if p.users.member?(u)
    end
    render(:text=>"$('s#{t.id}').src='/images/save.png';alert('user does not belong to project');") and return if !found
    #t.update_attributes(params[:task])
    t.title = params[:task][:title]
    t.priority = params[:task][:priority]
    t.done = params[:task][:done]
    t.duedate = params[:task][:duedate]
    t.user_id = u.id
    t.project_id = p.id
    t.save
    render(:text => "saved('#{t_id}',#{t.done})")
  end
  
  
  # Ajaxed
  def delete
    id = params[:id]
    t = Task.find(id)
    if t == nil or (t.project_id!=0 and not session['user'].projects.map {|p| p.id}.include?(t.project_id))
      render(:text=> '-1') # this task is assigned to a project but not to one of this user
      return
    end
    if Task.destroy(id)
      render(:text=>"#{id}")
    else
      render(:text=>'-2')
    end
  end
  
  def select_project_index
    id = params[:id]
    session['selectedproject'] = id.to_i
    select_task
    redirect_to(:action => 'index')
  end
  
  def get_project_resp p
    p_resp = find_responsibles(p).map{|u| u.name }
    str = "<div>Project members:<ul class=\"mylist\"><li>#{p_resp.join("</li><li>")}</li></ul></div>"
    flash[:members] = str
    str
  end
  
  #Ajaxed
  def show_project_resp
    str = get_project_resp params[:id].to_i
    render(:text => str)
  end
  
  #Ajaxed
  def select_project
    @projectid = session['selectedproject'] = params[:id].to_i
    select_task
    render(:partial=>"taskcontent")
  end
  
  def update_resp
    render(:partial => "respcontent")
  end
  
  #Ajaxed
  def select_resp
    session['selectedresp'] = params[:id]
    select_task
    render_partial("taskcontent")
  end
  
  #Ajaxed
  def order
    i = 1
    params[:taskslist].each { |id|
      Task.update(id, :order => i)
      i = i+1
    }
    render :nothing => true
  end
  
  def create_project
    render(:layout => false)
  end
  
  def export
    find_user_tasks
    str = "Order,Project,Priority,Title,Responsible,Due date\n"
    @tasks.each { |t|
      da = t.duedate.to_s
      str += '"'+t.order.to_s+'","'+t.project.name.to_s+'","'+t.priority.to_s+'","'+t.title.to_s+'","'+t.user.name.to_s+'","'+ da +"\"\n"
    }
    response.headers['Content-Type'] = 'text/csv'
    response.headers['Content-Disposition'] = 'attachment; filename=export.csv'
    render_text str
  end
  
  def sort_by_priority
    i = 1
    select_task
    # sort
    @tasks = @tasks.sort_by { |t|
      if(t.priority == nil)
        rv = [-1]
      else
        rv = [t.priority]
      end
      rv
    }
    @tasks.each { |t|
      Task.update(t.id, :order => i)
      i = i+1
    }
    redirect_to(:action => "index")
  end
  
  private
  
  def totext(hash)
    hash.to_a.join(", ")
  end
  
end
